import * as THREE       from 'three';
import {OrbitControls}  from 'three/examples/jsm/controls/OrbitControls';
import normalize        from './core/normalize';
import geoMesh          from './core/geomesh';
import {processGeoJSON} from "./mapshaper/index";
import { OBJExporter } from './core/objExporter';

const viewer = document.getElementById("main");
const width = viewer.offsetWidth;
const height = viewer.offsetHeight;


const renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(width, height);
viewer.appendChild(renderer.domElement);

const camera = new THREE.PerspectiveCamera(70, width / height, 1, 1000000000);
camera.position.set( -4e2, 6e3, -2e3 );

const control = new OrbitControls(camera, renderer.domElement);

const scene = new THREE.Scene();
const light = new THREE.DirectionalLight(0xffffff);
scene.add(light);

scene.add(new THREE.AxesHelper(20000000));

scene.add(new THREE.GridHelper(2000, 2));

const geoGroup = new THREE.Group();
scene.add(geoGroup);

function animate() {

    requestAnimationFrame( animate );

    light.position.set( camera.position.x, camera.position.y, camera.position.z ).normalize();

    renderer.render( scene, camera );

}
animate();

let geoObj;

fetch("./data/world.json")
    .then(res => res.json())
    .then(origin => {

        const opt = {
            featureTypes: ['Polygon', 'MultiPolygon'],
            minPolygonArea: 0,
            simplifyPct: 1,
            outputType: "extrude-surface"
        };

        processGeoJSON(origin, opt, function ({all, combine}) {

            const geojson = normalize(all, opt);

            const meshHelper = geoMesh(geojson, opt);

            const object = geoObj = meshHelper.create();

            object.rotateX(Math.PI / 2);
            object.rotateY(Math.PI);
            geoGroup.add(object);

            const helper = new THREE.BoxHelper( object, 0xffff00 );
            geoGroup.add( helper );
            geoGroup.add(getIndicator(meshHelper, [180, 30]));

        });

    });


function getIndicator(helper, [lon, lat]) {
    const [x, y] = helper.project([lon, lat]);
    var geometry = new THREE.SphereBufferGeometry( x / 200, 32, 32 );
    var material = new THREE.MeshBasicMaterial( { color: 0xee5555 } );
    var mesh = new THREE.Mesh( geometry, material );
    geometry.translate(x, y, 1);
    mesh.rotateX(Math.PI / 2);
    mesh.rotateY(Math.PI);
    return mesh;
}

function parseToObjString(object) {
    var exporter = new OBJExporter();
    var result = exporter.parse( object );
    return result;
}

function download(filename = 'geojson.obj', text) {
    const a = document.createElement('a');
    a.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
    a.setAttribute('download', filename);
    document.body.append(a);
    a.click();
    a.remove();
}

function downloadFile(getContent, suffix, splitBy = "o") {

    return function downloadObj() {
        const filename = 'geo.obj';

        console.log('downloading', filename);

        let text = getContent();

        if (splitBy === 'g') {
            text = text.split('\n').map(line => {
                if (line[0] === 'o') {
                    return 'g' + line.slice(1);
                }
                return line;
            }).join('\n');
        }
        download(filename, text);
    }
}

window.downloadObj = downloadFile(() => parseToObjString(geoObj), 'obj');